#include "Map.h"
using namespace std;
using namespace sf;

Map::Map(int headCount, int maximumX, int maximumY, int borderSize) :
	WALL_COLOR(WALL_COLOR), FREE_COLOR(Color::Black) {
	const Vector2f startPlayerSize(20, 20);
	for (int i = 0; i < headCount; i++) {
		Vector2f position(maximumX / 2, maximumY / 2);
		Head head(position, startPlayerSize, Color::Green, 100.0f, Vector2f(0, 1));
		heads.push_back(head);
	}

	barriers = Image(maximumX, maximumY, Color::Black);
	for (int y = 0; y < maximumY; y++) {
		for (int x = 0; x < maximumX; x++) {
			if (x < borderSize || x > maximumX - borderSize || y < borderSize || y > maximumY - borderSize) {
				barriers.SetPixel(x, y, Color::Yellow);
			}
		}
	}
}

void Map::checkForCollisions() {
	for (list<Head>::iterator i = heads.begin(); i != heads.end(); i++) {
		const Shape& shape = i->getCollisionShape();
		Color color = checkShapeBarrierCollision(shape);
		if (color != FREE_COLOR) {
			EnumerationCollisionTypes collisionType = TAIL;
			if (color == WALL_COLOR) {
				collisionType = WALL;
			}
			i->computeCollision(collisionType);
		}
	}
}

Color Map::checkShapeBarrierCollision(const Shape& shape) const {
	for (unsigned int i = 0; i < shape.GetNbPoints(); i++) {
		Vector2f pixel = shape.GetPointPosition(i);
		pixel = shape.TransformToGlobal(pixel);
		Color color = barriers.GetPixel((int) (pixel.x + 0.5), (int) (pixel.y + 0.5));
		if (color != FREE_COLOR) {
			return color;
		}
	}
	return FREE_COLOR;
}

void Map::update(float deltaTime) {
	list<Head>::iterator i = heads.begin();
	while (i != heads.end()) {
		i->update(deltaTime);
		//Shape shape = i->getNewTailPiece();
		//drawRectInImage(barriers, shape);
		++i;
	}
}

void Map::render(RenderWindow& renderWindow) {
	Sprite sprite;
	sprite.SetImage(barriers);
	renderWindow.Draw(sprite);
	for (list<Head>::iterator i = heads.begin(); i != heads.end(); i++) {
		i->render(renderWindow);
	}
	const Input& input = renderWindow.GetInput();
	if (input.IsKeyDown(Key::Left))
		heads.front().turnLeft();
	if (input.IsKeyDown(Key::Right))
		heads.front().turnRight();
}

void Map::reset() {
	// not yet implemented
}
